// 主要思路：把数字分为两组，每组都包含一个只出现一次的数字
// 如何分为两组
// 因为要找的那两个数字是不相等的，所以二者的二进制至少有一位不同，根据这个不同位，可以将数组
// 分为两类
// 1. 这个不同位上都是 1
// 2. 这个不同位上都是 0
// 这样就可以将数组分为两部分了
// 这里可以通过相反数进行与运算来获取最低位的 1，通过这个 1 将数组分为两组

var singleNumbers = function (nums) {
  // 定义一个 mask，表示要找的两个数字的异或
  // 因为出现了两次的数字的异或为 0，也就不会被记录在 mask 中
  let mask = 0;
  for (let num of nums) {
    mask ^= num;
  }
  // 获取到 mask 后，此时的任务就是找到其中一个只出现过一次的数字，记为 num1
  // 将 mask 与 num1 进行异或运算，就能获取到第二个数字，记为 num2

  // 异或结果的某一位是 1，表示当前位的运算数字一个是 1，一个是 0
  // 即找到了不同的一位，以下取最低位的 1

  // 获取最低位的 1，记为 diff
  let diff = mask & -mask;
  let num1 = 0;
  for (let num of nums) {
    // 若 num 和 diff 的与运算结果为 1，则说明这些 num 是一组的
    // 与此同时，结果为 0 的表示另一组
    // 原因是 异或为 1，表示运算数分别是 0 / 1
    if (num & diff) {
      // 此时的过程相当是在一堆数字中找到唯一的一个
      num1 ^= num;
    }
  }
  // 此时 num1 就是其中一个只出现一此的数字

  // 异或得到另外一个
  let num2 = mask ^ num1;
  return [num1, num2];
}